package com.wskj.workbench.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wskj.common.core.domain.entity.SysUser;
import com.wskj.common.core.mybatisplus.core.ServicePlusImpl;
import com.wskj.common.core.page.PagePlus;
import com.wskj.common.core.page.TableDataInfo;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.common.PageUtils;
import com.wskj.common.utils.common.SecurityUtils;
import com.wskj.common.utils.tool.Query;
import com.wskj.system.service.ISysUserService;
import com.wskj.workbench.bo.app.AppRankQueryBo;
import com.wskj.workbench.bo.app.AppRankTypeQueryBo;
import com.wskj.workbench.bo.app.AppSearchQueryBo;
import com.wskj.workbench.bo.app.AppTbUserWalletDetailQueryBo;
import com.wskj.workbench.bo.web.TbUserWalletDetailAddBo;
import com.wskj.workbench.bo.web.TbUserWalletDetailEditBo;
import com.wskj.workbench.bo.web.TbUserWalletDetailQueryBo;
import com.wskj.workbench.domain.TbUserWalletDetail;
import com.wskj.workbench.domain.TbUserWithdrawal;
import com.wskj.workbench.enums.UserWalletDetailDetailTypeEnum;
import com.wskj.workbench.enums.UserWalletDetailRecommendTypeEnum;
import com.wskj.workbench.mapper.TbUserWalletDetailMapper;
import com.wskj.workbench.service.ITbUserWalletDetailService;
import com.wskj.workbench.vo.app.*;
import com.wskj.workbench.vo.web.TbUserWalletDetailVo;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户的钱包明细Service业务层处理
 *
 * @author wskj
 * @date 2024-09-25
 */
@Service
@AllArgsConstructor(onConstructor_ = {@Lazy})
public class TbUserWalletDetailServiceImpl extends ServicePlusImpl<TbUserWalletDetailMapper, TbUserWalletDetail> implements ITbUserWalletDetailService {

    private ISysUserService sysUserService;


    @Override
    public TbUserWalletDetailVo queryById(Long id) {
        return getVoById(id, TbUserWalletDetailVo.class);
    }

    @Override
    public TableDataInfo<TbUserWalletDetailVo> queryPageList(TbUserWalletDetailQueryBo bo) {
        PagePlus<TbUserWalletDetail, TbUserWalletDetailVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), TbUserWalletDetailVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<TbUserWalletDetailVo> queryList(TbUserWalletDetailQueryBo bo) {
        return listVo(buildQueryWrapper(bo), TbUserWalletDetailVo.class);
    }

    private LambdaQueryWrapper<TbUserWalletDetail> buildQueryWrapper(TbUserWalletDetailQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TbUserWalletDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, TbUserWalletDetail::getUserId, bo.getUserId());
        lqw.eq(StrUtil.isNotBlank(bo.getRealName()), TbUserWalletDetail::getRealName, bo.getRealName());
        lqw.eq(StrUtil.isNotBlank(bo.getPhoneNumber()), TbUserWalletDetail::getPhoneNumber, bo.getPhoneNumber());
        lqw.eq(StrUtil.isNotBlank(bo.getDetailType()), TbUserWalletDetail::getDetailType, bo.getDetailType());
        lqw.eq(bo.getDetailPrice() != null, TbUserWalletDetail::getDetailPrice, bo.getDetailPrice());
        lqw.eq(StrUtil.isNotBlank(bo.getDelFlag()), TbUserWalletDetail::getDelFlag, bo.getDelFlag());
        // 如果不是超级管理员 需要查询所有下级用户列表
        if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            SysUser sysUser = sysUserService.selectUserById(SecurityUtils.getUserId());
            String inviteFullCode = sysUser.getInviteFullCode() + sysUser.getInviteCode();
            // 所有的用户下级
            List<Long> userIds = sysUserService.list(Wrappers.lambdaQuery(SysUser.class).likeRight(SysUser::getInviteFullCode, inviteFullCode)).stream()
                    .map(SysUser::getUserId).collect(Collectors.toList());


            if (ObjectUtil.isEmpty(userIds)) {
                lqw.in(TbUserWalletDetail::getUserId, 0);
            } else {
                lqw.in(ObjectUtil.isNotEmpty(userIds), TbUserWalletDetail::getUserId, userIds);
            }
        }
        lqw.orderByDesc(TbUserWalletDetail::getCreateTime);
        return lqw;
    }

    private LambdaQueryWrapper<TbUserWalletDetail> buildAppQueryWrapper(AppTbUserWalletDetailQueryBo bo) {

        LambdaQueryWrapper<TbUserWalletDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(TbUserWalletDetail::getUserId, SecurityUtils.getUserId());
        if (ObjectUtil.isNotEmpty(bo.getCreateTime())) {
            lqw.apply("DATE_FORMAT(CREATE_TIME,'%Y-%m-%d') = '" + bo.getCreateTime() + "'");
        }
        // 只查询推广的佣金(通过抖音导入别人贡献给我的+我自己推广的+平台赠送的)
        lqw.ne(TbUserWalletDetail::getDetailType, UserWalletDetailDetailTypeEnum.TIXIAN.getValue());
        lqw.isNotNull(TbUserWalletDetail::getRecommendType);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(TbUserWalletDetailAddBo bo) {
        TbUserWalletDetail add = BeanUtil.toBean(bo, TbUserWalletDetail.class);
        validEntityBeforeSave(add);
        SysUser sysUser = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getPhoneNumber, bo.getPhoneNumber())
                .eq(SysUser::getRealName, bo.getRealName()));

        // 判断用户是否有分红名额
        if (bo.getDetailType().equals(UserWalletDetailDetailTypeEnum.GUQUANZNEGSONG.getValue())) {
            AssertUtils.isTrue(sysUser.getContributeQuota().equals("2"), "用户没有股权分红名额");
        }
        add.setDetailType(bo.getDetailType());
        add.setUserId(sysUser.getUserId());
        add.setRealName(sysUser.getPhoneNumber());

        // 查询贡献人
        SysUser shareUser = sysUserService.getById(SecurityUtils.getUserId());
        if (ObjectUtil.isNotEmpty(shareUser)) {
            add.setRecommendType(UserWalletDetailRecommendTypeEnum.ZHITUI.getValue());
            add.setRecommendId(shareUser.getUserId());
            add.setRecommendName(shareUser.getRealName());
            add.setRecommendPhone(shareUser.getPhoneNumber());
            add.setRecommendAvatar(shareUser.getAvatar());
        }
        boolean save = save(add);

        // 添加明细
        sysUser.setTotalAmount(sysUser.getTotalAmount().add(bo.getDetailPrice()));

        sysUserService.updateById(sysUser);
        return save;
    }

    @Override
    public Boolean updateByEditBo(TbUserWalletDetailEditBo bo) {
        TbUserWalletDetail update = BeanUtil.toBean(bo, TbUserWalletDetail.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TbUserWalletDetail entity) {

        // 如果是新增 判断手机号是否存在
        if (ObjectUtil.isEmpty(entity.getId())) {
            long count = sysUserService.count(Wrappers.lambdaQuery(SysUser.class)
                    .eq(SysUser::getPhoneNumber, entity.getPhoneNumber())
                    .eq(SysUser::getRealName, entity.getRealName())

            );
            AssertUtils.isTrue(count != 0, "手机号和姓名不存在");
            AssertUtils.isTrue(entity.getDetailPrice().compareTo(BigDecimal.ZERO) > 0, "明细金额必须大于0");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        // 查询钱包明细
        for (Long id : ids) {
            TbUserWalletDetail tbUserWalletDetail = getById(id);
            if (ObjectUtil.isNotEmpty(tbUserWalletDetail)) {
                SysUser sysUser = sysUserService.getById(tbUserWalletDetail.getUserId());
                if (ObjectUtil.isNotEmpty(sysUser)) {
                    // 用户的余额减少
                    sysUser.setTotalAmount(sysUser.getTotalAmount().subtract(tbUserWalletDetail.getDetailPrice()));
                    sysUserService.updateById(sysUser);
                }
            }
        }
        boolean result = removeByIds(ids);
        return result;
    }

    @Override
    public String importTbUserWalletDetail(List<TbUserWalletDetailVo> tbUserWalletDetailList) {
        AssertUtils.isTrue(CollectionUtils.isNotEmpty(tbUserWalletDetailList), "导入数据不能为空");
        int successNum = 0;
        for (TbUserWalletDetailVo tbUserWalletDetail : tbUserWalletDetailList) {
            TbUserWalletDetail add = BeanUtil.toBean(tbUserWalletDetail, TbUserWalletDetail.class);
            save(add);
            successNum++;
        }
        String msg = String.format("导入完成，共计 %d 条数据，成功 %d 条！", tbUserWalletDetailList.size(), successNum);
        if (successNum != tbUserWalletDetailList.size()) {
            msg = msg + String.format("失败 %d 条！", tbUserWalletDetailList.size() - successNum);
        }
        return msg;
    }


    @Override
    public TableDataInfo<AppRankVo> getTypePage(Query query, AppRankTypeQueryBo bo) {
        Page<AppRankVo> pageTeam = baseMapper.getTypePage(PageUtils.buildPage(), bo);
        return PageUtils.buildDataInfo(pageTeam);
    }

    @Override
    public TableDataInfo<AppRankVo> getRankPage(Query query, AppRankQueryBo bo) {
        Page<AppRankVo> pageTeam = baseMapper.getRankPage(PageUtils.buildPage(), bo, SecurityUtils.getUserId());
        return PageUtils.buildDataInfo(pageTeam);
    }

    @Override
    public AppSearchVo search(AppSearchQueryBo bo) {

        AppSearchItemVo live = baseMapper.search(bo, "1");
        AppSearchItemVo video = baseMapper.search(bo, "2");

        // 提现信息
        AppSearchItemVo tixian = baseMapper.searchTixian(bo);


        // 直播收益
        List<BigDecimal> liveList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(live)) {
            if (ObjectUtil.isNotEmpty(tixian)) {
                liveList.add(live.getTodayRevenue().subtract(tixian.getTodayRevenue()));
                liveList.add(live.getWeekRevenue().subtract(tixian.getWeekRevenue()));
                liveList.add(live.getMonthRevenue().subtract(tixian.getMonthRevenue()));
            } else {
                liveList.add(live.getTodayRevenue());
                liveList.add(live.getWeekRevenue());
                liveList.add(live.getMonthRevenue());
            }
        }


        // 短视频收益
        List<BigDecimal> videoList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(video)) {
            if (ObjectUtil.isNotEmpty(tixian)) {
                liveList.add(video.getTodayRevenue().subtract(tixian.getTodayRevenue()));
                liveList.add(video.getWeekRevenue().subtract(tixian.getWeekRevenue()));
                liveList.add(video.getMonthRevenue().subtract(tixian.getMonthRevenue()));
            } else {
                videoList.add(video.getTodayRevenue());
                videoList.add(video.getWeekRevenue());
                videoList.add(video.getMonthRevenue());

            }
        }
        AppSearchVo appSearchVo = new AppSearchVo();
        appSearchVo.setLiveList(liveList);
        appSearchVo.setVideoList(videoList);

        return appSearchVo;
    }

    @Override
    public AppCurrentRankVo getRankCurrent(AppRankQueryBo bo) {
        SysUser sysUser = sysUserService.getById(SecurityUtils.getUserId());
        AppCurrentRankVo appCurrentRankVo = new AppCurrentRankVo();
        appCurrentRankVo.setRealName(sysUser.getRealName());
        appCurrentRankVo.setPhoneNumber(sysUser.getPhoneNumber());
        appCurrentRankVo.setSex(sysUser.getSex());
        appCurrentRankVo.setAvatar(sysUser.getAvatar());
        appCurrentRankVo.setUserId(SecurityUtils.getUserId());
        List<AppCurrentRankVo> rankCurrent = baseMapper.getRankCurrent(bo, SecurityUtils.getUserId());
        for (int i = 0; i < rankCurrent.size(); i++) {
            AppCurrentRankVo ar = rankCurrent.get(i);
            if (ar.getUserId().equals(SecurityUtils.getUserId())) {
                appCurrentRankVo.setRanking(i + 1);
                break;
            }
        }
        return appCurrentRankVo;
    }


    @Override
    public TableDataInfo<AppTbUserWalletDetailVo> walletRecord(Query query, AppTbUserWalletDetailQueryBo bo) {
        PagePlus<TbUserWalletDetail, AppTbUserWalletDetailVo> result = pageVo(PageUtils.buildPagePlus(), buildAppQueryWrapper(bo), AppTbUserWalletDetailVo.class);
        List<AppTbUserWalletDetailVo> recordsVo = result.getRecordsVo();
        for (AppTbUserWalletDetailVo appTbUserWalletDetailVo : recordsVo) {
            SysUser sysUser = sysUserService.getById(appTbUserWalletDetailVo.getUserId());
            if (ObjectUtil.isNotEmpty(sysUser)) {
                appTbUserWalletDetailVo.setAvatar(sysUser.getAvatar());
                appTbUserWalletDetailVo.setRealName(sysUser.getRealName());
            }
        }
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public BigDecimal getYesterdeyAmount() {

        BigDecimal yesterdeyAmount = baseMapper.getYesterdeyAmount(SecurityUtils.getUserId());

        return yesterdeyAmount;
    }

    @Override
    public BigDecimal getYesterdeyTixianAmount() {
        BigDecimal yesterdeyAmount = baseMapper.getYesterdeyTixianAmount(SecurityUtils.getUserId());
        return yesterdeyAmount;
    }
}
